float4x4 World;
float4x4 ViewProjection;

#define BASE_DIM 8
#define INV_BASE_DIM (1.0f / 8.0f)


sampler BaseData : register(s0);
sampler Mask : register(s1);

float2 BaseData(float x, float y)
{
	return tex2D(BaseData, float2(x,y)).xy;
}

float2 GridDir(float x, float y, float2 texCoord)
{
	return float2(texCoord.x - x, texCoord.y - y);
}



void VertexShaderFunction(float4 inPosition : POSITION0,
							float2 inTexCoord : TEXCOORD0,
							float3 inAux : NORMAL0,
							out float outRadius : PSIZE0,
							out float4 outPosition : POSITION0,
							out float2 outTexCoord : TEXCOORD0,
							out float3 outColor : COLOR
)
{
    float4 worldPosition = mul(inPosition, World);
    outPosition = mul(worldPosition, ViewProjection);
    outRadius = inAux.y / outPosition.z;
    
    outTexCoord = inTexCoord;
    outColor = inAux.x;
}

float Curve(float t)
{
	return (3 * t - 2) * t * t;
}

float4 PixelShaderFunction(float4 inPosition : POSITION0,
							float2 inTexCoord : TEXCOORD0,
							float inRadius : PSIZE,
							float3 inColor : COLOR) : COLOR0
{
	float2 GridFrac = float2(frac(inTexCoord.x * BASE_DIM),frac(inTexCoord.y * BASE_DIM));

	
	float leftGrid = ((int)(GridFrac.x * INV_BASE_DIM)) * INV_BASE_DIM;
	float rightGrid = leftGrid + INV_BASE_DIM;
	float topGrid = ((int)(GridFrac.y * INV_BASE_DIM)) * INV_BASE_DIM;
	float bottomGrid = topGrid + INV_BASE_DIM;
	
	float tlDot = dot(BaseData(leftGrid, topGrid), GridDir(leftGrid, topGrid, inTexCoord));
	float blDot = dot(BaseData(leftGrid, bottomGrid), GridDir(leftGrid, bottomGrid, inTexCoord));
	float trDot = dot(BaseData(rightGrid, topGrid), GridDir(rightGrid, topGrid, inTexCoord));
	float brDot = dot(BaseData(rightGrid, bottomGrid), GridDir(rightGrid, bottomGrid, inTexCoord));
	
	float2 CurveWeights = float2(Curve(GridFrac.x),Curve(GridFrac.y));
	
	float2 HLerps = float2(	lerp(tlDot, trDot, CurveWeights.x), 
							lerp(blDot, brDot, CurveWeights.x) );
	float final = lerp(HLerps.x, HLerps.y, CurveWeights.y);
	
	final.w = 1;
    return final;
}

technique Technique1
{
    pass Pass1
    {
        VertexShader = compile vs_2_0 VertexShaderFunction();
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}
